package crypto

import (
	"bytes"
	"errors"
	"fmt"

	"crypto/cipher"
	"crypto/des"

	"encoding/hex"

	"github.com/marspere/goencrypt"
)

func test() {
	data := "hello world"
	key := "12345678"
	iv := ""

	// result, err := DesECBEncrypt([]byte(data), []byte(key5))
	result, err := DesCBCEncrypt([]byte(data), []byte(key), []byte(iv))
	if err != nil {
		panic(err)
	}
	cipherText := hex.EncodeToString(result)
	fmt.Println(cipherText)

	cipherText, err = goencrypt.NewDESCipher([]byte(key), []byte(iv), goencrypt.ECBMode, goencrypt.Pkcs7, goencrypt.PrintBase64).DESEncrypt([]byte(data))
	if err != nil {
		panic(err)
	}
	fmt.Println(cipherText)
}

func DesECBEncrypt(data, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return nil, err
	}

	bs := block.BlockSize()
	data = pkcs5Padding(data, bs)
	if len(data)%bs != 0 {
		return nil, errors.New("need a multiple of the blocksize")
	}

	out := make([]byte, len(data))
	dst := out

	for len(data) > 0 {
		block.Encrypt(dst, data[:bs])
		data = data[bs:]
		dst = dst[bs:]
	}

	return out, nil
}
func DesCBCEncrypt(data, key, iv []byte) ([]byte, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return nil, err
	}

	bs := block.BlockSize()
	data = pkcs5Padding(data, bs)
	if len(data)%bs != 0 {
		return nil, errors.New("need a multiple of the blocksize")
	}

	cryptText := make([]byte, len(data))

	cipher.NewCBCEncrypter(block, iv).CryptBlocks(cryptText, data)

	return cryptText, nil
}

func pkcs5Padding(cipherText []byte, blockSize int) []byte {
	padding := blockSize - len(cipherText)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(cipherText, padText...)
}

// 分组模式
// CBCMode = iota
// CFBMode
// CTRMode
// ECBMode
// OFBMode

// 填充模式
// PkcsZero
// Pkcs7
// pkcs5padding
// iso10126
// ansix923

// 输出模式
// PrintHex
// PrintBase64
